package vmcs.controller;

import java.util.Observable;
import java.util.Observer;

import vmcs.common.Constant;
import vmcs.common.VMCSException;
import vmcs.machinery.Door;
import vmcs.simulationsystem.MachinerySimulationPanel;
import vmcs.store.Coin;
import vmcs.store.StoreController;
import vmcs.ui.interfacecontrol.*;


public class MachineryController implements Observer {

        public MainController mainCtrl;
        public StoreController storeCtrl;

        private IMachineryPanel ml;
        private Door door;

        
        
        public void initialize(MainController mctrl){
        	 mainCtrl = mctrl;
             storeCtrl = mctrl.getStoreController();
        }

        /**
 * This constructor creates a new instance of the MachineryController.  
 */
        
        public MachineryController() {              
                door = new Door();
        }

/**
 * This method returns the reference to the instance of MainController class.  
 * @return mainCtrl Reference to the instance of the MainController class.
 * @see MainController
 */
        
        public MainController getMainController() {
                return mainCtrl;
        }


/**
 * This method disposes the instance of {@link MachinerySimulationPanel}.  
 */
        
        public void closeDown() {
                if (ml != null)
                        ml.closeDown();
        }

        /* ************************************************************
         * Panel Operations
         */

/**
 * This method display the Machinery simulator panel.
 * @see MachinerySimulationPanel  
 */
        
        public void displayMachineryPanel() {
                ISimulatorPanel scp = mainCtrl.getSimulatorControlPanel();
                if (ml == null)
                        ml = UIController.getMachinerySimulatorPanel(scp, this);
                ml.display();
                //System.out.println("get door status:" + door.isDoorClosed());
                scp.setPanelActive(Constant.ACT_MACHINERY, false);
        }

/**
 * This method checks and disposes Machinery simulator panel. Before 
 * closing it checks state of the Door object whether it is closed or not.
 * @see MachinerySimulationPanel  
 */
        
        public void closeMachineryPanel() {
                if (ml == null)
                        return;
                boolean ds = isDoorClosed();

                if (ds == false) {
                	ml.showMessage("Please Lock the Door before You Leave");
                    return;
                }
                ml.closeDown();
                ISimulatorPanel scp = mainCtrl.getSimulatorControlPanel();
                scp.setPanelActive(Constant.ACT_MACHINERY, true);
        }

        /* ************************************************************
         * Door operation
         */

/**
 * This method returns the state of the door whether closed or opened
 * @return boolean status of the door closed
 * @see Door  
 */
        
        public boolean isDoorClosed() {
                return door.isDoorClosed();
        }

/**
 * This method set state of the door either close or open
 * @param state Door Close or Open
 * @see Door  
 */
        
        public void setDoorState(boolean state) {
                //System.out.println("StoreController.setDoorState:" + state);
                door.setState(state);
                displayDoorState();
        }

        /* ************************************************************
         * Display operation
         */

/**
 * This method display the state of the door on the machinery simulation panel.
 * @see MachinerySimulationPanel#setDoorState(boolean)  
 */
        public void displayDoorState() {
                if (ml == null)
                        return;
                ml.setDoorState(door.isDoorClosed());
        }

/**
 * This method updates drinks stock view on the machinery simulation panel.
 * @throws VMCSException Error during updating of drink stock view.
 * @see MachinerySimulationPanel#getDrinksStoreDisplay() 
 *//*
        
        // update drink stock view;
        public void displayDrinkStock() throws VMCSException {
                if (ml == null)
                        return;
                ml.updateDrinksStoreDisplay();
        }

*//**
 * This method updates coin stock view on the machinery simulation panel
 * after transfer all cash.
 * @throws VMCSException Error during updating of coin stock view.
 * @see MachinerySimulationPanel#getCashStoreDisplay()
 */
        
        // update coin stock view after transfer all cash;
        public void displayCoinStock() throws VMCSException {
                if (ml == null)
                        return;
               // ml.updateCashStoreDisplay();
        }

        /* ************************************************************
         * Interactions with the Store that need to update the display
         */

/**
 * This method interacts with store controller for updating cash store
 * that need to update the display
 * @throws VMCSException Error during updating of coin stock view.
 * @see MachinerySimulationPanel#getCashStoreDisplay()
 * @see StoreController#storeCoin(Coin)
 */
        
        public void storeCoin(Coin c) throws VMCSException {
                storeCtrl.storeCoin(c);
              
        }

/**
 * This method interacts with store controller for updating drinks store
 * that need to update the display
 * @throws VMCSException Error during updating of drinks stock view.
 * @see MachinerySimulationPanel#getDrinksStoreDisplay()
 * @see StoreController#dispenseDrink(int)
 */
        
        public boolean dispenseDrink(int idx) throws VMCSException {
               boolean status =  storeCtrl.dispenseDrink(idx);
              
                return status;
        }
        
/**
 * This method interacts with store controller for giving change
 * and update the coin stock view
 * @throws VMCSException Error during updating of drinks stock view.
 * @see MachinerySimulationPanel#getCashStoreDisplay()
 * @see StoreController#giveChange(int, int)
 */
        
        public void giveChange(int idx, int numOfCoins) throws VMCSException {
                storeCtrl.giveChange(idx, numOfCoins);
              
        }

@Override
public void update(Observable o, Object arg) {
	System.out.println("Update detected: " + this.toString());
	System.out.println("Object: "+arg.toString());
	if (ml != null){
		 ml.updateCashStoreDisplay();
		 ml.updateDrinksStoreDisplay();
	}
}

}
